{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Day13 re中的findall与finditer"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "　　通过前面这12天日程的学习积累，如果你有认真学习体会理解每天的内容，那么恭喜你已经成功get到**正则表达式**所有常用的语法，接下来剩余的日程，我就将继续带大家学习如何在`Python`中愉快地使用**正则表达式**。\n",
    "  \n",
    "　　今天作为后半程的开篇，我将带大家回顾之前使用过的`re`库中的`findall`，以及功能相同但更适用于大型数据的`finditer`。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "　　`re`作为`Python`中的标准库，提供了丰富的与**正则表达式**相关的API，其中`findall`功能最为基础，它的3个参数中的前两个参数`pattern`与`string`分别代表传入的**正则表达式**以及原始字符串，这里不作赘述，重点来介绍第3个参数`flags`，它的传入值是`re`中内置的一系列特殊对象，可以帮助我们实现很多方便的功能，下面来介绍其中常用的："
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- **re.IGNORECASE**\n",
    "\n",
    "　　`re.IGNORECASE`亦可简写为`re.I`，它的作用是使得我们的正则忽略字母的大小写区别："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2020-09-10T12:00:41.189942Z",
     "iopub.status.busy": "2020-09-10T12:00:41.188945Z",
     "iopub.status.idle": "2020-09-10T12:00:41.200912Z",
     "shell.execute_reply": "2020-09-10T12:00:41.199914Z",
     "shell.execute_reply.started": "2020-09-10T12:00:41.188945Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['cccddd']"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import re\n",
    "\n",
    "s = 'AAABBBcccddd'\n",
    "\n",
    "re.findall('[a-z]+', s)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2020-09-10T12:00:41.201910Z",
     "iopub.status.busy": "2020-09-10T12:00:41.201910Z",
     "iopub.status.idle": "2020-09-10T12:00:41.216869Z",
     "shell.execute_reply": "2020-09-10T12:00:41.215871Z",
     "shell.execute_reply.started": "2020-09-10T12:00:41.201910Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['AAABBBcccddd']"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "re.findall('[a-z]+', s, flags=re.I)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- **re.MULTILINE**\n",
    "\n",
    "　　`re.MULTILINE`亦可简写为`re.M`，它的作用体现在原始字符串中存在换行符时，将`^`的作用由定位字符串开始变为定位每一行的开始，将`$`的作用由定位字符串结尾变为定位每一行的结束："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2020-09-10T12:00:41.218865Z",
     "iopub.status.busy": "2020-09-10T12:00:41.217867Z",
     "iopub.status.idle": "2020-09-10T12:00:41.228838Z",
     "shell.execute_reply": "2020-09-10T12:00:41.228838Z",
     "shell.execute_reply.started": "2020-09-10T12:00:41.218865Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['abcd']"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "s = '''abcd\n",
    "efgh\n",
    "ijkl'''\n",
    "\n",
    "re.findall('^[a-z]{4,}', s)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2020-09-10T12:00:41.230832Z",
     "iopub.status.busy": "2020-09-10T12:00:41.230832Z",
     "iopub.status.idle": "2020-09-10T12:00:41.244794Z",
     "shell.execute_reply": "2020-09-10T12:00:41.243798Z",
     "shell.execute_reply.started": "2020-09-10T12:00:41.230832Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['abcd', 'efgh', 'ijkl']"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "re.findall('^[a-z]{4,}', s, flags=re.M)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- **re.DOTALL**\n",
    "\n",
    "　　亦可简写为`re.S`，我们在前面的学习中知晓了`.`可以代表任何非换行符的单个字符，而传入`flags=re.S`之后，`.`就可以真正意义上的代表任何单个字符："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2020-09-10T12:00:41.246789Z",
     "iopub.status.busy": "2020-09-10T12:00:41.245793Z",
     "iopub.status.idle": "2020-09-10T12:00:41.262748Z",
     "shell.execute_reply": "2020-09-10T12:00:41.261753Z",
     "shell.execute_reply.started": "2020-09-10T12:00:41.246789Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['第一行', '第二行', '第三行']"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "s = '''第一行\n",
    "第二行\n",
    "第三行'''\n",
    "\n",
    "re.findall('.+', s)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2020-09-10T12:00:41.264741Z",
     "iopub.status.busy": "2020-09-10T12:00:41.263743Z",
     "iopub.status.idle": "2020-09-10T12:00:41.275712Z",
     "shell.execute_reply": "2020-09-10T12:00:41.274714Z",
     "shell.execute_reply.started": "2020-09-10T12:00:41.264741Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['第一行\\n第二行\\n第三行']"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "re.findall('.+', s, flags=re.S)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "　　以上就是常用的`flags`参数可选值，接下来我们来介绍`finditer`，之所以说它更适用于大型数据，是因为它返回结果的独特机制："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2020-09-10T12:00:41.276709Z",
     "iopub.status.busy": "2020-09-10T12:00:41.276709Z",
     "iopub.status.idle": "2020-09-10T12:00:41.293663Z",
     "shell.execute_reply": "2020-09-10T12:00:41.293663Z",
     "shell.execute_reply.started": "2020-09-10T12:00:41.276709Z"
    }
   },
   "outputs": [],
   "source": [
    "s = 'abc'*100000"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2020-09-10T12:00:41.295659Z",
     "iopub.status.busy": "2020-09-10T12:00:41.294662Z",
     "iopub.status.idle": "2020-09-10T12:00:41.334554Z",
     "shell.execute_reply": "2020-09-10T12:00:41.333557Z",
     "shell.execute_reply.started": "2020-09-10T12:00:41.295659Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "list"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "result1 = re.findall('[a-z]{3}', s)\n",
    "type(result1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2020-09-10T12:00:41.335551Z",
     "iopub.status.busy": "2020-09-10T12:00:41.335551Z",
     "iopub.status.idle": "2020-09-10T12:00:41.353503Z",
     "shell.execute_reply": "2020-09-10T12:00:41.352506Z",
     "shell.execute_reply.started": "2020-09-10T12:00:41.335551Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "callable_iterator"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "result2 = re.finditer('[a-z]{3}', s)\n",
    "type(result2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2020-09-10T12:00:41.354501Z",
     "iopub.status.busy": "2020-09-10T12:00:41.354501Z",
     "iopub.status.idle": "2020-09-10T12:00:41.414341Z",
     "shell.execute_reply": "2020-09-10T12:00:41.414341Z",
     "shell.execute_reply.started": "2020-09-10T12:00:41.354501Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[<_sre.SRE_Match object; span=(0, 3), match='abc'>,\n",
       " <_sre.SRE_Match object; span=(3, 6), match='abc'>,\n",
       " <_sre.SRE_Match object; span=(6, 9), match='abc'>,\n",
       " <_sre.SRE_Match object; span=(9, 12), match='abc'>,\n",
       " <_sre.SRE_Match object; span=(12, 15), match='abc'>,\n",
       " <_sre.SRE_Match object; span=(15, 18), match='abc'>,\n",
       " <_sre.SRE_Match object; span=(18, 21), match='abc'>,\n",
       " <_sre.SRE_Match object; span=(21, 24), match='abc'>,\n",
       " <_sre.SRE_Match object; span=(24, 27), match='abc'>,\n",
       " <_sre.SRE_Match object; span=(27, 30), match='abc'>]"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "result2 = re.finditer('[a-z]{3}', s)\n",
    "temp = []\n",
    "for _ in result2:\n",
    "    temp.append(_)\n",
    "    \n",
    "temp[:10]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2020-09-10T12:00:41.416336Z",
     "iopub.status.busy": "2020-09-10T12:00:41.416336Z",
     "iopub.status.idle": "2020-09-10T12:00:41.423316Z",
     "shell.execute_reply": "2020-09-10T12:00:41.422319Z",
     "shell.execute_reply.started": "2020-09-10T12:00:41.416336Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'abc'"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "temp[0].group()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "　　因为是迭代器，所以只有在对其进行遍历时才会取到对应位置的元素，非常的节省内存。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Day13 课后小测验\n",
    "\n",
    "　　在学过今天的内容之后，请你提取出下面字符串中每一个单独的短句（譬如`公然放弃在主权争议上不持立场的\n",
    "承诺，直接介入本地区领土和海洋争端。仅上半年，`中的单独短句为`公然放弃在主权争议上不持立场的\n",
    "承诺`，`直接介入本地区领土和海洋争端`以及`仅上半年`）"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2020-09-10T12:00:41.425313Z",
     "iopub.status.busy": "2020-09-10T12:00:41.425313Z",
     "iopub.status.idle": "2020-09-10T12:00:41.436282Z",
     "shell.execute_reply": "2020-09-10T12:00:41.435284Z",
     "shell.execute_reply.started": "2020-09-10T12:00:41.425313Z"
    }
   },
   "outputs": [],
   "source": [
    "target = '''今年的最新动向，就是美国出于自身政治需要，公然放弃在主权争议上不持立场的\n",
    "承诺，直接介入本地区领土和海洋争端。仅上半年，美国就派出近3000架次军机、60余艘次军舰，\n",
    "包括多批次轰炸机和双航母编队，不断在南海炫耀武力，强化军事部署，甚至在与其毫不相干的争\n",
    "议海域横冲直撞，肆意推高地区冲突风险，正在成为南海军事化的最大推手。美国还对“南海行为\n",
    "准则”磋商指手划脚，干扰中国和东盟国家协商解决争议的努力，挑动地区国家对立对抗，美方的\n",
    "所做所为，就是要搞乱南海，搞乱地区，为推进其“印太战略”制造借口。'''"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2020-08-26T12:55:19.898241Z",
     "iopub.status.busy": "2020-08-26T12:55:19.897245Z",
     "iopub.status.idle": "2020-08-26T12:55:19.904225Z",
     "shell.execute_reply": "2020-08-26T12:55:19.903227Z",
     "shell.execute_reply.started": "2020-08-26T12:55:19.898241Z"
    }
   },
   "source": [
    "　　答案需与我在帖子下留言的标准答案保持一致，请将你的答案截图发到本帖评论区~"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['今年的最新动向',\n",
       " '就是美国出于自身政治需要',\n",
       " '公然放弃在主权争议上不持立场的承诺',\n",
       " '直接介入本地区领土和海洋争端',\n",
       " '仅上半年',\n",
       " '美国就派出近3000架次军机、60余艘次军舰',\n",
       " '包括多批次轰炸机和双航母编队',\n",
       " '不断在南海炫耀武力',\n",
       " '强化军事部署',\n",
       " '甚至在与其毫不相干的争议海域横冲直撞',\n",
       " '肆意推高地区冲突风险',\n",
       " '正在成为南海军事化的最大推手',\n",
       " '美国还对“南海行为准则”磋商指手划脚',\n",
       " '干扰中国和东盟国家协商解决争议的努力',\n",
       " '挑动地区国家对立对抗',\n",
       " '美方的所做所为',\n",
       " '就是要搞乱南海',\n",
       " '搞乱地区',\n",
       " '为推进其“印太战略”制造借口']"
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "[_.replace('\\n','') for _ in re.findall('([\\w“”\\\\n、]+)[，。]',target)]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.1"
  },
  "widgets": {
   "application/vnd.jupyter.widget-state+json": {
    "state": {},
    "version_major": 2,
    "version_minor": 0
   }
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
